package ar.com.photo_admin.service

import ar.com.photo_admin.domain.*;
import javax.annotation.*
import org.codehaus.groovy.grails.commons.GrailsApplication;
import org.apache.commons.io.*

class RemoteFileHostingService extends BaseService {

	def commandTool;
	def bucketUrl;
	def curlCommandTool;
	def finishUploadUrl;
	def photosHostedUrl;
	def hostedInWindows;
	def windowsConsolePrefix;
	
	def RemoteFileHostingService(){
		
		
	}
	
	@PostConstruct
	def initService(){		
		bucketUrl = grailsApplication.config.gcs.appplication.bucketUrl
		commandTool = grailsApplication.config.gcs.config.commandTool
		curlCommandTool = grailsApplication.config.curl.config.installedPath
		finishUploadUrl = grailsApplication.config.gcs.appplication.finishUploadUrl		
		photosHostedUrl = grailsApplication.config.gcs.commons.photosHostedUrl
		hostedInWindows = grailsApplication.config.hostedInWindows
		windowsConsolePrefix = grailsApplication.config.windowsConsolePrefix
	}
	
	@Deprecated
    def publish(Event event) {
						
		//Debugging purposes...
		def sout = new StringBuffer()
		def serr = new StringBuffer()
		
		//Comando ejecutado para subir las fotos a GCS.			
		String uploadCommand = "${commandTool} cp -a public-read -R ${getEventNotHostedPhotosPath(event.number)}/* ${bucketUrl+event.number}/"
		log.info "Subiendo las fotos a GCS"
		log.info "Ejecutando comando a GCS: " +uploadCommand		
		
		//Comando ejecutado una vez que termina de ejecutar el programa para avisarle al servidor que procese lo que se almaceno				
		String notifyCommand = "${curlCommandTool} ${finishUploadUrl}?eventId=${event.id} "		
		log.info "Al terminar se avisara a la aplicación comando a GCS: " +notifyCommand 		
		//Process notifyProc = notifyCommand.execute()
				
		//Process uploadAndNotifyAfter = ("cmd /c ${uploadCommand} &  ${notifyCommand}").execute()
		Process uploadAndNotifyAfter = ("cmd /c ${uploadCommand} &  ${notifyCommand}").execute()
		uploadAndNotifyAfter.consumeProcessOutput(sout,serr)			
		
    }
	
	def registerUploadToHosting(def eventId){
		log.info "Registrando las imagenes subidas" 
		Event event = Event.get(eventId)
		event = event.refresh()
		
		def photosUploaded = getSuccessfullyUploadedPhotos(event)
		
		def allPhotosUploadedCorrectly = true;
		
		photosUploaded.each {EventPhoto photo ->		
			try{
				def hostedPath = getEventHostedPhotosPath(event.number)
				def number = event.number
				def fullImageName = FilenameUtils.getName(photo.pathInServer)
				def mImageName = FilenameUtils.getName(photo.thumbnailMediumPathInServer)
				def sImageName = FilenameUtils.getName(photo.thumbnailPathInServer)
				

				//Actualizo los urls en el host
				photo.urlInHost = photosHostedUrl + number + "/" +  fullImageName
				photo.thumbnailMediumUrlInHost = photosHostedUrl + number + "/" + mImageName
				photo.thumbnailUrlInHost = photosHostedUrl + number + "/" + sImageName
				
				photo.hosted = true;
				
				photo.save(flush:true)	
			}
			catch (IOException ex){
				allPhotosUploadedCorrectly = false;
				log.error "No se pudo mover el archivo (IO exception)"
				log.error ex.message
			}
			catch (Exception ex){
				allPhotosUploadedCorrectly = false;
				log.error "No se pudo mover el archivo"
				log.error ex.message
			}
		}
		
		if (allPhotosUploadedCorrectly){
			log.info "Todas las fotos del evento ${event.id} han sido subidas"
			event.published = true
			event.save(flush:true)
		}
	}
	
	def getSuccessfullyUploadedPhotos(Event event){			
		
		//def logFilename =  "listado.txt"
		
		
		//def listCommand = "${ hostedInWindows ? windowsConsolePrefix : ''} ${commandTool} ls -l ${bucketUrl+event.number} > ${eventLogFile}"
		def listCommand = "${ hostedInWindows ? windowsConsolePrefix : ''} ${commandTool} ls -l ${bucketUrl+event.number}"
		log.info "Obteniendo un listado de las fotos subidas al hosting"
		log.info "Ejecutando comando a GCS: " + listCommand
		
		def sout = new StringBuffer()
		def serr = new StringBuffer()
		
		//Ejecuto el proceso
		Process listProc = listCommand.execute()
		listProc.consumeProcessOutput(sout,serr)			
		listProc.waitFor()
		

		def pattern = ~/[a-zA-Z0-9:\- ]* gs:\/\/[a-zA-Z0-9\-_]*\/\d+\/[a-zA-Z0-9\-_]*\.[a-zA-Z]*/
		
		log.info "Listado provisto por GCS: \n" + sout
		
		// A partir del archivo de listado extraigo las urls de las fotos subidas
		def photoUrls = []
		//new File(eventLogFile).eachLine { line ->
		sout.eachLine { line ->
			if (pattern.matcher(line).matches()){
					def parts = line.split("/")	
					photoUrls.add(parts[parts.size()-1])
			}											 
		}		
		log.info "Imagenes en GCS: " + photoUrls
					
		//Recupero las imagenes del evento que se deben procesar como hosteadas
		def newHostedPhotos = []
		event.photos.each { EventPhoto photo ->
			if (!photo.hosted){
				def fullImage = FilenameUtils.getName(photo.pathInServer)
				def mImage = FilenameUtils.getName(photo.thumbnailMediumPathInServer)
				def sImage = FilenameUtils.getName(photo.thumbnailPathInServer)
				if (photoUrls.contains(fullImage) && photoUrls.contains(mImage) && photoUrls.contains(sImage)){					
					newHostedPhotos.add(photo)
				}
			}
		}
		
		return newHostedPhotos		
	}
}
